using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using org.tmatesoft.svn.core;
using org.tmatesoft.svn.core.wc;

namespace Subsync.Core.Subversion
{
	/// <summary>
	/// Author: Steven Goh Jian Wen
	/// SVN Checkout
	/// </summary>
	public class SVNCheckout : CommandBase
	{
		/// <summary>
		/// We have our variables declared here.
		/// Access modifiers as you can observe, is public. Why?
		/// Because we trust our programmers.
		/// 
		/// Try to be verbose with the variable names.
		/// Also, try to include *sane defaults*. Take peg_revision for eg.
		/// </summary>
		private SVNURL checkout_url;
		private java.io.File destination_path;
		private SVNRevision peg_revision = SVNRevision.UNDEFINED;
		private SVNRevision revision = SVNRevision.HEAD;
		private SVNDepth depth = SVNDepth.INFINITY; //infinity means recursive
		private bool allow_unversioned_obstructions = true;

		/// <summary>
		/// Sane default constructor.
		/// </summary>
		/// <param name="checkout_url">
		/// A <see cref="System.String"/>
		/// </param>
		public SVNCheckout (string checkout_url)
		{
			Debug.WriteLine ("SVN Checkout minimal Constructor with sane defaults");

            //for auto appending. creating sane default.
            //ie: http://blabla.com/svn/trunk/dev will checkout the folder into <current_dir>/dev
            string[] url_split = checkout_url.Split(new char[] { '/', '\\' });

            this.checkout_url = SVNURL.parseURIEncoded(checkout_url);
            this.destination_path = new java.io.File(Path.Combine(Directory.GetCurrentDirectory(), url_split[url_split.Length - 1]));
		}

        public SVNCheckout(string checkout_url, string dest_path)
        {
			this.checkout_url = SVNURL.parseURIEncoded(checkout_url);
			this.destination_path = new java.io.File(dest_path);
        }
				
		/// <summary>
		/// Full constructor for Checkout.
		/// </summary>
		/// <param name="checkout_url_str">
		/// A <see cref="System.String"/>
		/// </param>
		/// <param name="dest_path">
		/// A <see cref="System.String"/>
		/// </param>
		/// <param name="peg_rev">
		/// A <see cref="SVNRevision"/>
		/// </param>
		/// <param name="co_rev">
		/// A <see cref="SVNRevision"/>
		/// </param>
		/// <param name="depth">
		/// A <see cref="SVNDepth"/>
		/// </param>
		/// <param name="allow_unv_obs">
		/// A <see cref="System.Boolean"/>
		/// </param>
		public SVNCheckout(string checkout_url_str,string dest_path,
		                   SVNRevision peg_rev, SVNRevision co_rev,
		                   SVNDepth depth, Boolean allow_unv_obs) 
		{
			//DEBUG MSG. *Always* include this.
			Debug.WriteLine("SVN Checkout normal Constructor");
			
			this.checkout_url = SVNURL.parseURIEncoded(checkout_url_str);
			this.destination_path = new java.io.File(dest_path);
			this.peg_revision = peg_rev;
			this.revision = co_rev;
			this.depth = depth;
			this.allow_unversioned_obstructions = allow_unv_obs;
		}
		
		/// <summary>
		/// Execute SVN Checkout
		/// </summary>
		public override void Execute ()
		{
			Debug.WriteLine("SVN Checkout Execution");
			
			//library setup
			Tools.SetupLibrary();
			
			//load up the clients
			SVNClientManager cm = SVNClientManager.newInstance();
			SVNUpdateClient uc = cm.getUpdateClient();
						
			try {
				uc.doCheckout(this.checkout_url, this.destination_path, 
				              this.peg_revision, this.revision, this.depth, 
				              this.allow_unversioned_obstructions);						
			}
			catch (SVNException e) {
				//we convert this exception to a non SVNKit exception.
				//we want to minimize interfacing with SVNkit outside of this namespace (abstraction)
				throw new SVNExecuteException(e.getMessage());
			}
		}
	}
}




